<template>
  <div class="app-container">
    <el-row v-if="queryshow" :gutter="10">
      <el-col v-for="(item,index) in queryList" :key="item.value" :xs="6" :sm="6" :md="5" :lg="5" :xl="5">
        <div class="flexstyle" v-if="item.input">
          <span>{{item.label}} :</span><el-input style="width:100%" size="small" v-model="form[item.value]" :placeholder="item.label" clearable />
        </div>
        <div class="flexstyle" v-if="item.select">
          <span>{{item.label}} :</span>
          <el-select style="width:100%" :disabled="item.disabled" clearable size="small" @change="(e)=>queryRemoteMethod(e,item.filter,true,index,form[item.value])"  @focus="queryRemoteMethod('',item.filter,false,index)"  v-model="form[item.value]"  :filterable="item.filter" :remote="item.filter" :remote-method="(e)=>queryRemoteMethod(e,item.filter,false,index)">
              <el-option v-for="it in item.list" :key="it.value" :label="it.label" :value="it.value" />
          </el-select>
        </div>
        <div class="flexstyle" v-if="item.daterange">
          <span>{{item.label}} :</span>
          <el-date-picker v-model="form[item.value]" size="small" value-format="yyyy-MM-dd HH:mm:ss"  type="daterange" :default-time="['00:00:00', '23:59:59']" range-separator="至" start-placeholder="开始日期"  end-placeholder="结束日期">
          </el-date-picker>
        </div>
        <!-- value-format="yyyy-MM-dd" -->
      </el-col>
      <el-col :xs="6" :sm="6" :md="4" :lg="4" :xl="4" style="display:flex">
        <el-button type="primary" plain @click="getQuery">搜索</el-button>
        <el-button type="primary" plain @click="reset">重置</el-button>
      </el-col>
    </el-row>
    <div>
      <slot></slot>
    </div>
    <!-- 列表 -->
    <el-table ref="myTable" v-loading="loading" :style="{width:tableWidth}" 
    @selection-change="selectChange" 
    @select="tableSelect"
    :data="tableList"  
    :height="height" 
    :row-style="rowStyle" 
    :row-class-name="rowClassName"
    @row-click="changeCurrentRow"
    @expand-change="clickNestTable">
      <el-table-column v-if="showselection" type="selection" width="55"> </el-table-column>
      <el-table-column v-if="nestTable" prop="" label="" type="expand" width="30">
        <template v-slot="scope">
          <!-- 嵌套表格 -->
          <el-table :data="scope.row[nestTableValue] || []" style="width: 100%;margin-bottom: 20px;" border >
            <el-table-column v-for="item in nestTableColumnn" :key="item.prop" :label="item.label" align="center" :prop="item.prop">
              <template slot-scope="scope">
                <div>
                  <!-- 函数返回数据 -->
                  <span v-if="item.func">{{item.showFunc(scope.row) }}</span>
                  <!-- 普通的 -->
                  <span v-if="item.pu">{{scope.row[item.prop]}}</span>
                  <!-- 普通的带有判断的 -->
                  <span v-if="item.pan">{{item.showobj[scope.row[item.prop]] }}</span>
                  <!-- 展示时间的 -->
                  <span v-if="item.time">{{ parseTime(scope.row[item.prop],item.ruleTime) }}</span>
                  <!-- 根据字段展示不同的状态 -->
                  <el-tag v-if="item.tag" :type="tagType[scope.row[item.prop]]" >{{tagValue[scope.row[item.prop]]}}</el-tag>

                  <!-- 表格交互操作 -->
                  <!-- 下拉选 -->
                  <el-select v-if="item.select" :multiple="item.multiple" @visible-change="(e)=>visiblechange(e,item.filter,scope.$index,item.value)" :disabled="item.disabled" @change="(e)=>remoteMethod(e,item.filter,true,scope.$index,item)" :filterable="item.filter" :remote="item.filter" :remote-method="(e)=>remoteMethod(e,item.filter,false,scope.$index,item)" v-model="scope.row[item.value]" >
                    <el-option v-for="it in scope.row[item.value + 'edittablelist']" :key="it.zouvalue" :label="it.zoulabel" :value="it.zouvalue" />
                  </el-select>
                  <!-- 输入框 -->
                  <el-input v-if="item.input" :type="item.inputType" v-model="scope.row[item.value]" :disabled="item.disabled" />
                  <!-- 时间选择器 -->
                  <el-date-picker v-if="item.date" :placeholder="'请选择'+item.label" clearable v-model="scope.row[item.value]" :disabled="item.disabled" type="date" value-format="timestamp"  />
                   <!-- 图片 -->
                  <el-image v-if="item.image && scope.row[item.prop]" fit="contain" :src="scope.row[item.prop]"></el-image>
                </div>
              </template>
            </el-table-column>
            <el-table-column v-if="nestOperation" label="操作" align="center" class-name="small-padding fixed-width">
              <template slot-scope="scop">
                <div  v-for="item in nestAlloperation" :key="item.value" :class="item.btnClass || ''">
                  <el-button  :size="item.size || 'mini'" :type="item.btnType || 'text'" @click="nestOperationFun(scop.row,item.type,scop.$index,scope.row,scope.$index)">{{item.pan ? item.obj[scop.row[item.objvalue]] :item.value}}</el-button>
                </div>
                
              </template>
            </el-table-column>
          </el-table>
        </template>
      </el-table-column>
      <el-table-column v-if="xuhao" label="序号" align="center" type="index" />
      <el-table-column v-for="item in tableColumnn" :key="item.prop" :label="item.label" :width="item.width" align="center" :prop="item.prop">
        <template slot-scope="scope">
          <div>
            <!-- 函数返回数据 -->
            <span v-if="item.func">{{item.showFunc(scope.row) }}</span>
            <!-- 普通的 -->
            <span v-if="item.pu">{{scope.row[item.prop]}}</span>
            <!-- 普通的,且可以点击的 -->
            <span class="clickStyle" v-if="item.puClick" @click="clickTableRow(scope.row,item)">{{scope.row[item.prop]}}</span>
            <!-- 普通的对象型 -->
            <span v-if="item.puobj">{{scope.row[item.propObj][item.prop]}}</span>
            <!-- 普通的带有判断的 -->
            <span v-if="item.pan">{{item.showobj[scope.row[item.prop]] || '' }}</span>
            <!-- 展示时间的 -->
            <span v-if="item.time">{{ parseTime(scope.row[item.prop]) }}</span>
            <!-- 展示图片 -->
            <img @click="clickTableRow(scope.row,item)" style="width:100px;height:100px;" v-if="item.img" :src="scope.row[item.prop]" alt="">
            <!-- 根据字段展示不同的状态 -->
            <el-tag v-if="item.tag" :type="tagType[scope.row[item.prop]]" >{{tagValue[scope.row[item.prop]]}}</el-tag>
            <!-- <el-tooltip v-if="item.tooltip" placement="top">
              <div slot="content" v-for="(it,ind) in Object.keys(item.forobj) ?? []" :key="ind">
                <div v-for="(val,valindex) in item.list" :key="valindex">
                  {{val.label}} : {{val.value}} <br/>
                </div>
              </div>
              <el-button>{{item.btnName}}</el-button>
            </el-tooltip> -->
            <el-select v-if="item.select" :multiple="item.multiple" @visible-change="(e)=>visiblechange(e,item.filter,scope.$index,item.value)" :disabled="item.disabled" @change="(e)=>remoteMethod(e,item.filter,true,scope.$index,item)" :filterable="item.filter" :remote="item.filter" :remote-method="(e)=>remoteMethod(e,item.filter,false,scope.$index,item)" v-model="scope.row[item.value]" >
              <el-option v-for="(it,selectind) in scope.row[item.value + 'edittablelist']" :key="selectind" :label="it.zoulabel" :value="it.zouvalue" />
          </el-select>
          <el-input v-if="item.input" :placeholder="'请输入'+item.label" @input="(e)=>tableInput(e,item.zheng,scope.$index,item.value)" @blur="tableBlur(item.blur,scope.row[item.value],scope.$index,item.value,scope.row)" :type="item.inputType" v-model="scope.row[item.value]" :disabled="item.disabled" />
            <!-- 时间选择器 -->
            <el-date-picker v-if="item.date" :placeholder="'请选择'+item.label" clearable v-model="scope.row[item.value]" :disabled="item.disabled" type="date" value-format="timestamp"  />
            <!-- 图片 -->
            <el-image v-if="item.image && scope.row[item.prop]" fit="contain" :src="scope.row[item.prop]"></el-image>
          </div>
        </template>
      </el-table-column>
      <el-table-column v-if="operation && operationFixed" label="操作" align="center" class-name="small-padding fixed-width" fixed="right" :min-width="operationMinWidth || ''">
        <template slot-scope="scope">
          <div  v-for="item in alloperation" :key="item.value" :class="item.btnClass || ''">
            <el-button v-show="showfuns(scope.row,item.showarr)" :size="item.size || 'mini'" :type="item.btnType || 'text'" @click="operationFun(scope.row,item.type,scope.$index)">{{item.pan ? item.obj[scope.row[item.objvalue]] :item.value}}</el-button>
          </div>
          
        </template>
      </el-table-column>
      <el-table-column v-if="operation && !operationFixed" label="操作" align="center" class-name="small-padding fixed-width">
        <template slot-scope="scope">
          <div  v-for="item in alloperation" :key="item.value" :class="item.btnClass || ''">
            <el-button v-show="showfuns(scope.row,item.showarr)" :size="item.size || 'mini'" :type="item.btnType || 'text'" @click="operationFun(scope.row,item.type,scope.$index)">{{item.pan ? item.obj[scope.row[item.objvalue]] :item.value}}</el-button>
          </div>
          
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
                @pagination="getList"/>
  </div>
</template>

<script>

export default {
  name: "myTable",
  components: {
  },
  data() {
    return {
      // 遮罩层
      loading: false,
      // 租户列表
      list: [],
      // 查询参数
      queryParams: {
        pageNo: 1,
        pageSize: 10
      },
      form:{},
      currentRowId:null,
    };
  },
  props:{
    tableList:{     // 列表数据
      type:Array,  
      default:()=>[]
    },
    total:{      // 总条数
      type:Number,
      default:0
    },
    tableColumnn:{ //表格框主要内容 pu:普通的列 pan:有判断功能的列 time:展示时间的列 tag: tag标签列
      type:Array,
      default:()=>[]
    },
    xuhao:{  //  是否展示序号
      type:Boolean,
      default:false
    },
    showselection:{  //  是否展示多选框
      type:Boolean,
      default:false
    },
    selectList:{   // 多选框选中的数据
      type:Array,
      default:()=>[]
    },
    operation:{  //  是否展示表格操作
      type:Boolean,
      default:true
    },
    operationFixed:{  //  表格操作是否固定在右侧
      type:Boolean,
      default:true
    },
    queryshow:{  //  是否展示搜索操作
      type:Boolean,
      default:false
    },
    paramsform:{
      type:Object,
      default:()=>({})
    },
    alloperation:{ //操作内容及类型 a: 详情,b: 编辑,c: 删除,d: 打印
      type:Array,
      default:()=>[]
    },
    queryList:{ //搜索条件数组 value: 搜索条件的值,name: 搜索条件名称
      type:Array,
      default:()=>[]
    },
    deleteUrl:{
      type:String,
      default:''
    },
    tagType:{   //  tag标签展示什么样的样式 '':蓝色,'success':绿色,,'info':灰色,,'danger':红色,,'warning':黄色,
      type:Object,
      default:()=>({})
    },
    tagValue:{  // tag标签里面展示的内容
      type:Object,
      default:()=>({})
    },
    clickcolumnShow:{ // 判断点击行是否使用
      type:Boolean,
      default:false
    },
    height:{      // table高度
      type:Number,
      default:null
    },
    tableWidth:{   // table的宽度
      type:String,
      default:'100%'
    },
    nestTable:{   //  是否展示嵌套表格
      type:Boolean,
      default:false
    },
    nestOperation:{   //  是否展示嵌套表格操作
      type:Boolean,
      default:false
    },
    nestAlloperation:{  // 嵌套表格操作列表 和外层操作内容一样
      type:Array,
      default:()=>[]
    },
    nestTableValue:{ // 嵌套表格列表
      type:String,
      default:''
    },
    nestTableColumnn:{  // 嵌套表格列表
      type:Array,
      default:()=>[]
    },
    operationMinWidth:{  // 操作列的最小宽度
      type:String,
      default:''
    },
    rowConditionChangeColor:{  // 是否启用行根据条件变色
      type:Boolean,
      default:false
    },
    rowConditionChangeColorArr:{  // 行条件变色参数和值
      type:Array,
      default:()=>[]
    },
  },
  created() {
    // this.getList();
    // if(this.clickcolumnShow) this.currentRowId = this.tableList[0]?.id
  },
  computed:{
  },
  mounted(){
    this.$nextTick(()=>{
      this.currentRowId = this.tableList[0]?.id ?? null
      this.rowStyle({row:{id:this.currentRowId}})
    })
    
  },
  watch:{
    paramsform (newValue, oldValue){
      this.form = this.paramsform
    },
    form (newValue, oldValue){
      this.$emit('update:paramsform', newValue)
    },
  },
  mounted(){
    // this.$nextTick(function() {
    //   console.log(222222,this.clickcolumnShow,this.tableList)
    //   if(this.clickcolumnShow && this.tableList.length !== 0){
    //     console.log(this.tableList[0],33333,this.clickcolumnShow,this.$refs.myTable,this.$refs.myTable.setCurrentRow(this.tableList[0]))
        
    //       console.log(11111,this.$refs.myTable.setCurrentRow(this.tableList[0]))
    //       this.$refs.myTable.setCurrentRow(this.tableList[0])
        
    //   }
    // })
    
  },
  methods: {
    /** 查询列表 */
    getList() {
      this.$emit('gettabledata',{...this.queryParams,...this.form}) // 重新获取表格数据
    },
    getQuery(){
      this.queryParams.pageNo = 1
      this.getList()
    },
    reset(){ // 重置按钮操作
      this.form={}
      this.queryParams.pageNo = 1
      this.$emit('gettabledata',this.queryParams)
    },
    // 操作
    nestOperationFun(row,type,index,fatherRow,fatherIndex){
      this.$emit('nestSuperFun',row,index,type,fatherRow,fatherIndex)
    },
    // 操作
    operationFun(row,val,index){
      switch(val){
        case 'a':
          this.$emit('detailFun',row,index);break;
        case 'b':
          this.$emit('editFun',row,index);break;
        case 'c':
          this.$emit('deleteFun',row,index);break;
        case 'd':
          this.$emit('printFun',row,index);break;
        case 'e':
          this.$emit('allFun',row,index);break;
        default:this.$emit('superFun',row,index,val)
      }
    },
    clickNestTable(row,rowArr){ // 展开嵌套表格时触发
      // this.$refs.myTable.toggleRowExpansion(row, false)
      if(rowArr.length === 0) return
      this.$emit('clickNestTable',row,rowArr)
    },
    changeCurrentRow(row, column, event) {  // 点击行变色
      if(event.target.tagName.toLowerCase() == 'span') return
      if(!this.clickcolumnShow) return
      let index = null
      this.tableList.forEach((item,inde)=>{
        if(row.id === item.id) index=inde
      })
      // row.id字段可以是数据列表中的任意唯一字段
      if (this.currentRowId === row.id) return
      this.currentRowId = row.id
      this.$emit('clickcolumns',row,index)
    },
    rowStyle ({row, rowIndex}) {
      if(!this.clickcolumnShow) return
      if (this.currentRowId === row.id) {
        // 此处返回选中行的样式对象，按需设置
        return {
          'background-color': '#bedbb1',
        }
      }
    },
    showfuns(a,b){  // 判断是否展示某个操作
      let arr = b ?? []
      if(arr.length === 0) return true
      let bb = arr.every(item=>{
        let bbb = item.arrValue.some(ite=>{
          return a[item.key] === ite
        })
        return  bbb
      })
      return bb
    },
    clickTableRow(row,item){ // 点击表格行时触发
      this.$emit('clickTableRow',row,item) // 参数为 表格行内容和表格行的其他数据，例如label和prop
    },
    remoteMethod(e,val,changes,index,item){   // 下拉框远程搜索方法
      if(val){
        
        // 选中时调用
        if(changes === true){
          // 查出选中的那一行
          let row = {}
          if(this.tableList[index][item.value+'edittablelist'] instanceof Array && item.contrast){
            row = this.tableList[index][item.value+'edittablelist'].find(ite=>ite.zouvalue === e) ?? {}
          }
          this.$emit('remoteMethods',e,true,index,item.value+'edittablelist',row)
          return 
        } 
        this.$emit('remoteMethods',e,false,index,item.value+'edittablelist')  // 查询时调用
      }
    },
    visiblechange(e,val,index,str){  // 点击下拉框，去模糊查询
      if(val){
        if(e === true) this.$emit('visiblechange',index,str+'edittablelist')
        this.$emit('remoteMethods','',false,index,str+'edittablelist')
      }
      
    },
    selectChange(e){   /// 勾选checkbox 时触发,当选择项发生变化时会触发该事件
      this.$emit('update:selectList',e)
    },
    tableSelect(e,row){ // 当用户手动勾选数据行的 Checkbox 时触发的事件
      this.$emit('selectChange',e,row)
    },
    queryRemoteMethod(e,filte,change,index,value){ // 查询列表select的选中和查询方法 change 为true 选中，false 查询
      if(filte){
        // 选中
        if(change) return this.$emit('queryRemoteMethod',e,true,index,value)
        // 查询
        this.$emit('queryRemoteMethod',e,false,index)
      }
      
    },
    tableInput(e,pan,index,name){ // 表格input框，input事件
      // 只取正数
      if(pan){
        if(e.indexOf('0') == 0 && e.length > 1)this.$set(this.tableList[index],name,e.substring(1,a.length))
          
        if(Number(e) < 0) this.$set(this.tableList[index],name,0)
      }
    },
    tableBlur(pan,value,index,inputvalue,row){  // 在表格输入框失去焦点时触发
      if(pan){
        this.$emit('tableBlurs',value,index,inputvalue,row)
      }
    },
    setCurrentRow(row){//选中某一行
      this.currentRowId = row.id
      this.$refs.myTable.setCurrentRow(row)
    },
    toggleAllSelection(){
      this.$refs.myTable.toggleAllSelection()
    },
    rowClassName(row, rowIndex){  // 根据条件变色
      // 是否启用行根据条件变色
      if(this.rowConditionChangeColor){
        let backColor // 背景色
        const a = this.rowConditionChangeColorArr.some(item=>{
          const b = item.value.some(ite=>row[item.condition] === ite)
          if(b){
            backColor = item.backColor
            return true
          }
        })
        if(a) return backColor
        return
      }
      if (this.currentRowId === row.row.id){
        return "active"
      }
      return ""
    }
  }
};
</script>
<style scoped lang="scss">
.app-container{
  .el-col{
    margin-bottom: 10px;
    
  }
  .el-table{
    margin-top: 20px;
  }
  .el-table .fixed-width .el-button:not([type="text"]){
      padding-left: 7px;
      padding-right: 7px;
      margin-bottom:5px;
  }
}
.flexstyle{
  display: flex;
  span{
    font-size: 14px;
    color: #606266;
    font-weight: 600;
    // display: inline-block;
    width: 120px;
    display: flex;
    // justify-content: center;
    align-items: center;
  }
}
.clickStyle{
  color: #0b5af6;
  cursor: pointer;
}
// 背景色
::v-deep .el-table .blue {
  background-color: rgb(102, 177, 255)!important;
  // color: #fff;
}
::v-deep .el-table .green {
  background-color: rgb(133, 206, 57)!important;
  // color: #fff;
}
::v-deep .el-table .gray {
  background-color: rgb(144, 147, 153)!important;
  // color: #fff;
}
::v-deep .el-table .yellow {
  background-color: rgb(230, 162, 60)!important;
  // color: #fff;
}
::v-deep .el-table .red {
  background-color: rgb(245, 108, 108)!important;
  // color: #fff;
}
</style>